package com.credithc.signature.job.workshop;


import com.credithc.signature.job.po.Task;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class SignatureMaster {

    /**
     * 存放任务的队列
     */
    private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<>();

    /**
     * 将线程交给线程池托管
     */
    private ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue());

    /**
     * 执行任务的工人
     */
    private AbstractWorker worker;

    /**
     * 工人的数量
     */
    private int workerCount;

    /**
     * 保存执行结果
     */
    private ConcurrentHashMap<Integer, Object> resultMap = new ConcurrentHashMap<Integer, Object>();

    /**
     * 构造方法,传入worker和worker数量
     *
     * @param worker
     * @param workerCount
     */
    public SignatureMaster(AbstractWorker worker, int workerCount) {
        this.worker = worker;
        this.workerCount = workerCount;
        worker.setWorkQueue(workQueue);
        worker.setResultMap(resultMap);
        pool.setCorePoolSize(workerCount);
        pool.setMaximumPoolSize(workerCount);
    }

    /**
     * 提交任务
     *
     * @param task
     */
    public void submit(Task task) {
        workQueue.add(task);
    }

    /**
     * 执行任务
     */
    public void execute() {
        for (int i = 0; i < workerCount; i++) {
            pool.execute(worker);
        }
    }

    /**
     * 判断所有线程是否执行完毕
     *
     * @return
     */
    public boolean isCompleted() {
        return pool.isTerminated();
    }

    /**
     * 执行完成
     */
    public void completed() {
        pool.shutdown();
    }

    /**
     * 获取最终执行结果
     *
     * @return
     */
    public int getResult() {
        int res = 0;
        for (Map.Entry<Integer, Object> resItem : resultMap.entrySet()) {
            res += (int) resItem.getValue();
        }
        return res;
    }
}
